package com.fansl.allround.oss.service;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.ContentType;
import com.alibaba.fastjson.JSONObject;
import com.fansl.allround.oss.api.config.QiniuOssPropertiesConfig;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.Region;
import com.qiniu.storage.UploadManager;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author fansl
 * @Description: 阿里云服务
 * @date 2019/9/2 17:24
 */
@Slf4j
@Service
@AllArgsConstructor
public class QiniuOssService {
    private final QiniuOssPropertiesConfig qiniuOssPropertiesConfig;

    /**
     * 获取上传凭证
     * @param key 文件名称(客户端上传代码中指定的文件名，两者必须一致)
     * @return
     */
    public String getUploadToken(String key) {
        return getUploadToken(key,false);
    }

    /**
     * 获取上传凭证
     * @param key 文件名称(客户端上传代码中指定的文件名，两者必须一致)
     * @param isPrivate 是否是私有空间
     * @return
     */
    public String getUploadToken(String key,boolean isPrivate) {
        String bucketName = qiniuOssPropertiesConfig.getBucketNamePub();
        if(isPrivate){
            bucketName = qiniuOssPropertiesConfig.getBucketName();
        }

        Auth auth = createAuth();
        //自定义上传回复内容
        StringMap putPolicy = new StringMap();
        putPolicy.put("returnBody", "{\"key\":\"$(key)\",\"hash\":\"$(etag)\",\"bucket\":\"$(bucket)\",\"fsize\":$(fsize)}");
        //回调业务地址
        String callbackUrl = qiniuOssPropertiesConfig.getCallbackUrl();
        if(StrUtil.isNotBlank(callbackUrl)){
            putPolicy.put("callbackUrl", callbackUrl);
            putPolicy.put("callbackBody", "{\"key\":\"$(key)\",\"hash\":\"$(etag)\",\"bucket\":\"$(bucket)\",\"fsize\":$(fsize)}");
            putPolicy.put("callbackBodyType", ContentType.JSON);
        }
        //凭证过期时间
        long expireSeconds = qiniuOssPropertiesConfig.getExpireInSeconds();

        String uptoken = auth.uploadToken(bucketName,key,expireSeconds,putPolicy);
        log.info("七牛云文件上传凭证获取：{}",uptoken);
        return uptoken;
    }
    /**
     * 上传文件
     * @param file
     * @return
     */
    public String uploadFile(MultipartFile file) {
        return uploadFile(file,false);
    }
    /**
     * 上传文件
     * @param file
     * @param isPrivate 是否是私有空间
     * @return
     */
    public String uploadFile(MultipartFile file,boolean isPrivate) {
        try {
            if(file.isEmpty()){
                log.warn("七牛云上传文件为空");
                return null;
            }
            Configuration cfg = new Configuration(Region.autoRegion());
            UploadManager uploadManager = new UploadManager(cfg);
            String originalFilename=  file.getOriginalFilename();
            String fileName = DateUtil.format(new Date(),DatePattern.PURE_DATE_PATTERN)
                    +"/"+originalFilename.toLowerCase().substring(originalFilename.indexOf(".")+1,originalFilename.length())
                    +"/"+originalFilename;
            log.info("七牛云key：{}",fileName);

            String token = getUploadToken(fileName,isPrivate);
            Response response = uploadManager.put(file.getBytes(),fileName,token);

            log.info("七牛云上传文件返回：{}",JSONObject.toJSONString(response.bodyString()));
            return getDownloadUrl(fileName,isPrivate);

        } catch (Exception e) {
            log.error("七牛云上传文件异常",e);
            throw new RuntimeException("上传文件异常");
        }
    }

    /**
     * 获取下载URL
     * @param key
     * @param isPrivate
     * @return
     */
    public String getDownloadUrl(String key,boolean isPrivate){
        try {
            if(isPrivate){
                String domainOfBucket = qiniuOssPropertiesConfig.getDomainOfBucket();
                String encodedFileName = URLEncoder.encode(key, "utf-8").replace("+", "%20");
                String downloadUrl = String.format("%s/%s", domainOfBucket, encodedFileName);
                //一小时过期时间
                long expireInSeconds = 3600;
                String finalUrl = createAuth().privateDownloadUrl(downloadUrl,expireInSeconds);
                return finalUrl;
            }else {
                String domainOfBucket = qiniuOssPropertiesConfig.getDomainOfBucketPub();
                String encodedFileName = URLEncoder.encode(key, "utf-8").replace("+", "%20");
                String finalUrl  = String.format("%s/%s", domainOfBucket, encodedFileName);
                return finalUrl;
            }
        }catch (Exception e){
            log.error("七牛云获取下载URL异常",e);
        }
        return "";
    }
    public Auth createAuth(){
        String accessKey = qiniuOssPropertiesConfig.getAccessKeyId();
        String secretKey = qiniuOssPropertiesConfig.getAccessKeySecret();
        Auth auth = Auth.create(accessKey,secretKey);
        return auth;
    }

    public Map<String,String> getDownloadUrlList(List<String> keys, boolean isPrivate) {
        Map<String,String> result = new HashMap<>(keys.size());
        keys.forEach(key->{
            result.put(key,getDownloadUrl(key,isPrivate));
        });
        return result;
    }
}
